import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:pp_uikit/tabbar/pp_custom_width_indicator.dart';
import 'package:pp_uikit/tabbar/pp_tabbar_controller.dart';
import 'package:pp_uikit/tabbar/pp_tabbar_item.dart';
import 'package:pp_uikit/tabbar/pp_tabbar_theme.dart';
import 'package:pp_uikit/theme/pp_default_theme.dart';

/// PPTabBarBadge的tab分配模式
enum PPTabBarBadgeMode {
  /// 原始的默认TabBar的分配模式
  origin,

  /// 默认的按照4.5等分模式
  average
}

/// 单个tab选中的回调
/// [state]:当前组件的State对象，[PPTabBarState]
/// [index]:当前组件的角标
typedef PPTabBarOnTap = Function(PPTabBarState state, int index);

/// 带小红点的Tabbar
// ignore: must_be_immutable
class PPTabBar extends StatefulWidget {
  /// PPTabBarBadge填充的数据，长度匹配控制器的TabController.length
  final List<PPTabBarItem> tabs;

  /// 视图的自定义构造器
  final Widget Function(PPTabBarItem item, bool isSelect)? tabsBuilder;

  /// [PPTabBar] 的tab模式
  /// 默认：[PPTabBarBadgeMode.average]（按照屏幕平均分配模式）
  final PPTabBarBadgeMode mode;

  /// 是否能滑动(当tab数量大于4个，默认都是滚动的，再设置此属性无效)
  final bool isScroll;

  /// Tabbar的整体高度
  final double? tabHeight;

  /// TabBar的padding
  final EdgeInsetsGeometry padding;

  /// 控件宽度最多容纳几个
  final int scrollableLimitTabLength;

  /// 控制Tab的切换
  TabController? controller;

  /// 数据处理控制器
  PPTabbarController? tabbarController;

  /// TabBar背景颜色
  final Color? backgroundcolor;

  /// 指示器的颜色
  final Color? indicatorColor;

  final Color? badgeColor;

  /// 指示器的高度
  final double? indicatorWeight;

  /// 指示器的宽度
  final double? indicatorWidth;

  final EdgeInsetsGeometry? indicatorPadding;

  /// 选中Tab文本的颜色
  final Color? labelColor;

  /// 选中Tab文本的样式
  final TextStyle? labelStyle;

  /// Tab文本的Padding
  final EdgeInsetsGeometry labelPadding;

  /// 未选中Tab文本的颜色
  final Color? unselectedLabelColor;

  /// 未中Tab文本的样式
  final TextStyle? unselectedLabelStyle;

  /// 处理拖拽开始行为方式，默认DragStartBehavior.start
  final DragStartBehavior dragStartBehavior;

  /// Tab的选中点击事件
  final PPTabBarOnTap? onTap;

  /// 添加的Tab的宽度(指定tabWidth就不会均分屏幕宽度)
  final double? tabWidth;

  /// 是否显示分隔线
  final bool hasDivider;

  /// 是否显示角标
  final bool hasIndex;

  /// 展开更多Tabs
  final bool showMore;

  /// 展开更多弹框标题
  final String? moreWindowText;

  /// 更多弹框弹出的时候
  final VoidCallback? onMorePop;

  /// tag间距
  final double? tagSpacing;

  /// 每行tag数
  final int? preLineTagCount;

  /// tag高度
  final double? tagHeight;

  double fontSize;

  PPTabBarTheme? themeData;

  PPTabBar({
    Key? key,
    required this.tabs,
    this.tabsBuilder,
    this.mode = PPTabBarBadgeMode.average,
    this.isScroll = false,
    this.tabHeight,
    this.padding = EdgeInsets.zero,
    this.controller,
    this.tabbarController,
    this.backgroundcolor,
    this.indicatorColor,
    this.indicatorWeight,
    this.indicatorWidth,
    this.indicatorPadding,
    this.badgeColor,
    this.labelColor,
    this.labelStyle,
    this.fontSize = 14,
    this.labelPadding = EdgeInsets.zero,
    this.unselectedLabelColor,
    this.unselectedLabelStyle,
    this.dragStartBehavior = DragStartBehavior.start,
    this.onTap,
    this.tabWidth,
    this.hasDivider = false,
    this.hasIndex = false,
    this.showMore = false,
    this.moreWindowText,
    this.onMorePop,
    this.themeData,
    this.tagSpacing,
    this.preLineTagCount,
    this.tagHeight,
    this.scrollableLimitTabLength = 4,
  }) : super(key: key) {
    themeData ??= PPTabBarTheme();
    tabbarController ??= PPTabbarController();
  }

  @override
  // ignore: no_logic_in_create_state
  PPTabBarState createState() {
    var state = PPTabBarState();
    return state;
  }
}

class PPTabBarState extends State<PPTabBar> with TickerProviderStateMixin {
  /// 小红点文案
  late String _badgeText;

  /// 小红点容器内边距
  late EdgeInsets _badgePadding;

  /// 小红点高度
  // ignore: unused_field
  late double _largeSize;

  /// 小红点上偏移量
  double _dy = 0;

  /// 小红点右偏移量
  double _dx = 0;

  PPTabBarState();

  @override
  void initState() {
    super.initState();
    // 监听更多弹框tab选中变化的时候
    widget.tabbarController?.addListener(() {
      // 更新TabBar选中位置
      if (widget.controller != null) {
        widget.controller!.animateTo(widget.tabbarController!.selectIndex);
      }
      // 刷新选中TabBar小红点
      refreshBadgeState(widget.tabbarController!.selectIndex);
      // 更新Tabbar更多图标样式
      setState(() {});
    });

    widget.controller?.addListener(_handleTabIndexChangeTick);
  }

  @override
  void dispose() {
    super.dispose();
    widget.controller?.removeListener(_handleTabIndexChangeTick);
  }

  void _handleTabIndexChangeTick() {
    if (widget.controller?.index.toDouble() ==
        widget.controller?.animation?.value) {
      widget.tabbarController?.selectIndex = widget.controller?.index ?? 0;
      widget.tabbarController?.isShow = false;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: widget.padding,
      constraints: BoxConstraints(minHeight: widget.themeData!.tabHeight),
      color: widget.backgroundcolor ?? widget.themeData!.backgroundColor,
      child: DefaultTabController(
        length: widget.tabs.length,
        child: _buildTabBar(),
      ),
    );
  }

  // 构建TabBar样式
  TabBar _buildTabBar() {
    bool isScrollable = widget.tabs.length > widget.scrollableLimitTabLength ||
        widget.tabWidth != null ||
        widget.isScroll;

    List<Widget> tabs;
    if (widget.tabsBuilder != null) {
      tabs = <Widget>[];
      for (var i = 0; i < widget.tabs.length; i++) {
        var item = widget.tabs[i];
        tabs.add(widget.tabsBuilder!(
            item, widget.tabbarController?.selectIndex == i));
      }
    } else {
      tabs = fillWidgetByDataList(isScrollable);
    }

    return TabBar(
        tabs: tabs,
        controller: widget.controller,
        isScrollable: isScrollable,
        labelColor: widget.labelColor ?? widget.themeData!.labelStyle.color,
        labelStyle: widget.labelStyle ?? widget.themeData!.labelStyle,
        labelPadding: widget.labelPadding,
        unselectedLabelColor: widget.unselectedLabelColor ??
            widget.themeData!.unselectedLabelStyle.color,
        unselectedLabelStyle: widget.unselectedLabelStyle ??
            widget.themeData!.unselectedLabelStyle,
        dragStartBehavior: widget.dragStartBehavior,
        onTap: (index) {
          if (widget.onTap != null) {
            widget.onTap!(this, index);
            widget.tabbarController?.setSelectIndex(index);
            widget.tabbarController?.isShow = false;
            widget.tabbarController?.entry?.remove();
            widget.tabbarController?.entry = null;
          }
        },
        indicator: CustomWidthUnderlineTabIndicator(
          insets: widget.indicatorPadding ?? widget.labelPadding,
          borderSide: BorderSide(
            width: widget.themeData!.indicatorHeight,
            color: widget.indicatorColor ?? widget.themeData!.labelStyle.color!,
          ),
          width: widget.themeData!.indicatorWidth,
        ));
  }

  // 更新选中tab的小红点状态
  void refreshBadgeState(int index) {
    setState(() {
      PPTabBarItem badgeTab = widget.tabs[index];
      if (badgeTab.isAutoDismiss) {
        badgeTab.badgeNum = null;
        badgeTab.badgeText = null;
        badgeTab.showRedBadge = false;
      }
    });
  }

  List<Widget> fillWidgetByDataList(bool isScrollable) {
    List<Widget> widgets = <Widget>[];
    List<PPTabBarItem> tabList = widget.tabs;
    if (tabList.isNotEmpty) {
      double? minWidth;
      if (widget.tabWidth != null) {
        minWidth = widget.tabWidth;
      } else {
        double tabUseWidth = MediaQuery.of(context).size.width;
        if (tabList.length <= widget.scrollableLimitTabLength) {
          minWidth = tabUseWidth / tabList.length;
        } else {
          minWidth = tabUseWidth / 4.5;
        }
      }
      for (int i = 0; i < tabList.length; i++) {
        PPTabBarItem badgeTab = tabList[i];
        if (widget.mode == PPTabBarBadgeMode.average) {
          widgets.add(
              _wrapAverageWidget(badgeTab, minWidth, i == tabList.length - 1));
        } else {
          widgets.add(_wrapOriginWidget(
              badgeTab, i == tabList.length - 1, isScrollable));
        }
      }
    }
    return widgets;
  }

  // 原始的自适应的tab样式
  Widget _wrapOriginWidget(
      PPTabBarItem badgeTab, bool lastElement, bool isScrollable) {
    var contentWidget = LayoutBuilder(builder: (context, constraints) {
      caculateBadgeParams(badgeTab, constraints);
      return Container(
        alignment: Alignment.center,
        height: 47,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Visibility(
                visible: widget.hasIndex && badgeTab.topText != null,
                child: Text(
                  badgeTab.topText ?? "",
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                )),
            Badge(
              isLabelVisible: (badgeTab.badgeNum != null
                      ? badgeTab.badgeNum! > 0
                      : false) ||
                  badgeTab.showRedBadge ||
                  (badgeTab.badgeText != null
                      ? badgeTab.badgeText!.isNotEmpty
                      : false),
              label: Text(
                _badgeText,
                style: const TextStyle(
                    color: Color(0xFFFFFFFF), fontSize: 10, height: 1),
              ),
              backgroundColor:
                  widget.badgeColor ?? PPDefaultTheme.instance.brandPrimary,
              alignment: Alignment.topLeft,
              offset: Offset(_dx, _dy),
              padding: _badgePadding,
              largeSize: _largeSize,
              child: Text(
                badgeTab.text!,
                maxLines: 1,
                softWrap: true,
                textAlign: TextAlign.center,
                overflow: TextOverflow.ellipsis,
                style: const TextStyle(fontSize: 16),
              ),
            )
          ],
        ),
      );
    });

    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        isScrollable
            ? contentWidget
            : Expanded(
                child: contentWidget,
              ),
        Visibility(
          visible: widget.hasDivider && !lastElement,
          child: Container(
            width: 1,
            height: 20,
            color: const Color(0xffe4e6f0),
          ),
        )
      ],
    );
  }

  // 定制的等分tab样式
  Widget _wrapAverageWidget(
      PPTabBarItem badgeTab, double? minWidth, bool lastElement) {
    return LayoutBuilder(builder: (context, constraints) {
      caculateBadgeParams(badgeTab, constraints);
      return Container(
        width: minWidth,
        alignment: Alignment.center,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(
                child: Container(
              alignment: Alignment.center,
              height: 47,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Visibility(
                      visible: widget.hasIndex && badgeTab.topText != null,
                      child: Text(
                        badgeTab.topText ?? "",
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      )),
                  Badge(
                    isLabelVisible: (badgeTab.badgeNum != null
                            ? badgeTab.badgeNum! > 0
                            : false) ||
                        badgeTab.showRedBadge ||
                        (badgeTab.badgeText != null
                            ? badgeTab.badgeText!.isNotEmpty
                            : false),
                    backgroundColor: widget.badgeColor ??
                        PPDefaultTheme.instance.brandPrimary,
                    label: Text(
                      _badgeText,
                      style: const TextStyle(
                          color: Color(0xFFFFFFFF), fontSize: 10, height: 1),
                    ),
                    alignment: Alignment.topLeft,
                    offset: Offset(_dx, _dy),
                    padding: _badgePadding,
                    largeSize: _largeSize,
                    child: Text(badgeTab.text!,
                        textAlign: TextAlign.center,
                        maxLines: 1,
                        softWrap: true,
                        overflow: TextOverflow.ellipsis,
                        style: const TextStyle(fontSize: 16)),
                  ),
                  // sub title
                  // Text(
                  //   badgeTab.text!,
                  //   maxLines: 1,
                  //   softWrap: true,
                  //   textAlign: TextAlign.center,
                  //   overflow: TextOverflow.ellipsis,
                  //   style: TextStyle(fontSize: widget.fontSize),
                  // ),
                ],
              ),
            )),
            Visibility(
              visible: widget.hasDivider && !lastElement,
              child: Container(
                width: 1,
                height: 20,
                color: const Color(0xffe4e6f0),
              ),
            )
          ],
        ),
      );
    });
  }

  // 计算小红点尺寸相关参数
  void caculateBadgeParams(PPTabBarItem badgeTab, BoxConstraints constraints) {
    _dy = -5.0;

    if (badgeTab.badgeNum != null) {
      if (badgeTab.badgeNum! < 10) {
        _badgePadding = const EdgeInsets.only(left: 5.0, right: 5.0);
        _largeSize = 16.0;
        _badgeText = badgeTab.badgeNum?.toString() ?? "";
      } else if (badgeTab.badgeNum! > 99) {
        _badgePadding = const EdgeInsets.fromLTRB(4, 3, 4, 2);
        _largeSize = 16.0;
        _badgeText = "99+";
      } else {
        _badgePadding = const EdgeInsets.fromLTRB(4, 3, 4, 2);
        _largeSize = 16.0;
        _badgeText = badgeTab.badgeNum?.toString() ?? "";
      }
    } else {
      if (badgeTab.badgeText != null && badgeTab.badgeText!.isNotEmpty) {
        _badgePadding = const EdgeInsets.fromLTRB(6, 3, 6, 3);
        _largeSize = 16.0;
        _badgeText = badgeTab.badgeText?.toString() ?? "";
      } else {
        _badgePadding = const EdgeInsets.only(left: 4.0, right: 4.0);
        _largeSize = 8.0;
        _badgeText = "";
        _dy = 1.0;
      }
    }

    // 获取 tabTextWidth
    TextStyle tabTextStyle =
        const TextStyle(overflow: TextOverflow.ellipsis, fontSize: 16);
    TextPainter tabTextPainter = TextPainter(
        locale: Localizations.localeOf(context), textAlign: TextAlign.center);
    tabTextPainter.textDirection = TextDirection.ltr;
    tabTextPainter.maxLines = 1;
    tabTextPainter.text = TextSpan(text: badgeTab.text, style: tabTextStyle);
    tabTextPainter.layout(maxWidth: constraints.maxWidth);
    double tabTextWidth = tabTextPainter.width;

    // 获取 badgeTextWidth
    TextStyle badgeTextStyle = const TextStyle(height: 1, fontSize: 10);
    TextPainter badgeTextPainter =
        TextPainter(textScaleFactor: MediaQuery.of(context).textScaleFactor);
    badgeTextPainter.textDirection = TextDirection.ltr;
    badgeTextPainter.maxLines = 1;
    badgeTextPainter.text = TextSpan(text: _badgeText, style: badgeTextStyle);
    badgeTextPainter.layout(maxWidth: constraints.maxWidth);
    // 红点内 text 的宽度
    double badgeTextWidth = badgeTextPainter.width;

    double badgeWidth = badgeTextWidth + _badgePadding.horizontal;

    // 获取外部传入的tab padding值
    EdgeInsets labelPadding = widget.labelPadding.resolve(TextDirection.ltr);

    if ((tabTextWidth + badgeWidth) >
        (constraints.maxWidth + labelPadding.right)) {
      // 如果tab文字宽度 + 红点宽度  > 约束宽度（父容器宽度）+ 设置tab 右padding  则将红点左移 红点宽度偏移量
      // if(_badgeWidth > (constraints.maxWidth + labelPadding.right)){
      //   _paddingRight = 0.0;
      // }else{
      // _paddingRight = constraints.maxWidth + labelPadding.right - badgeWidth;
      _dx = constraints.maxWidth + labelPadding.right - badgeWidth;
      // }
    } else {
      // _paddingRight = tabTextWidth;
      _dx = tabTextWidth;
    }
  }
}
